/* 
 *  Syntelos XB
 *  Copyright (C) 2006 John Pritchard.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License as
 *  published by the Free Software Foundation; either version 2 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307 USA
 */

package syntelos.xb;

/**
 * <p> Interface common to both {@link CF} and {@link XB}, for {@link
 * Base}. </p>
 * 
 * @see XB
 * @see CF
 * @see Base
 * 
 * @author John Pritchard (jdp@syntelos.com)
 */
public interface IO
    extends syntelos.iou.dom.Node,
            syntelos.iou.dom.CharacterData.User,
            syntelos.iou.dom.rw.Compile.Node1,
            syntelos.iou.dom.rw.Decompile.Node1
{
    public final static byte ZED_BYTE = (byte)0;
    public final static char ZED_CHAR = (char)0;

    public interface Reader {

        public int offset();
    }
    public interface Writer {

        public int offset();
    }
    /**
     * Data types
     */
    public abstract class Data 
    {
        /**
         * Standard DOM compatiblility: application data type zero is
         * DOM default type (string).
         */
        public final static int STRING    = 0x00;

        /**
         * The following types match to instruction {@link
         * syntelos.xb.op.Newarray `newarray'}.  See JVM Spec
         * (Lindholm & Yellin, 2nd Ed) page 343.
         */
        public final static int BOOLEAN   = 0x04;
        public final static int CHAR      = 0x05;
        public final static int FLOAT     = 0x06;
        public final static int DOUBLE    = 0x07;
        public final static int BYTE      = 0x08;
        public final static int SHORT     = 0x09;
        public final static int INTEGER   = 0x0a;
        public final static int LONG      = 0x0b;

        /**
         * All consts (and OP as well) have type value greater than
         * CONST.  The CONST data type value itself is used to
         * reference any CONST value.
         */
        public final static int CONST = 0xff;

        public final static int CONST_CLASS         = CF.Constants.CLASS + CONST;
        public final static int CONST_FIELDREF      = CF.Constants.FIELDREF + CONST;
        public final static int CONST_METHODREF     = CF.Constants.METHODREF + CONST;
        public final static int CONST_IMETHODREF    = CF.Constants.IMETHODREF + CONST;
        public final static int CONST_STRING        = CF.Constants.STRING + CONST;
        public final static int CONST_INTEGER       = CF.Constants.INTEGER + CONST;
        public final static int CONST_FLOAT         = CF.Constants.FLOAT + CONST;
        public final static int CONST_LONG          = CF.Constants.LONG + CONST;
        public final static int CONST_DOUBLE        = CF.Constants.DOUBLE + CONST;
        public final static int CONST_NAME_AND_TYPE = CF.Constants.NAME_AND_TYPE + CONST;
        public final static int CONST_UTF8          = CF.Constants.UTF8 + CONST;

        /**
         * All {@link Op}'s have type 'OP'
         */
        public final static int OP = 0xffff;

        /**
         * All {@link syntelos.xb.at.Variable}'s have type 'VAR'
         */
        public final static int VAR = 0xffffff;


        private final static syntelos.iou.objmap dict = new syntelos.iou.objmap(33);
        static {
            dict.put("string",new java.lang.Integer(STRING));
            dict.put("boolean",new java.lang.Integer(BOOLEAN));
            dict.put("char",new java.lang.Integer(CHAR));
            dict.put("float",new java.lang.Integer(FLOAT));
            dict.put("double",new java.lang.Integer(DOUBLE));
            dict.put("byte",new java.lang.Integer(BYTE));
            dict.put("short",new java.lang.Integer(SHORT));
            dict.put("int",new java.lang.Integer(INTEGER));
            dict.put("long",new java.lang.Integer(LONG));

            dict.put("java.lang.String",new java.lang.Integer(STRING));
            dict.put("java.lang.Boolean",new java.lang.Integer(BOOLEAN));
            dict.put("java.lang.Character",new java.lang.Integer(CHAR));
            dict.put("java.lang.Float",new java.lang.Integer(FLOAT));
            dict.put("java.lang.Double",new java.lang.Integer(DOUBLE));
            dict.put("java.lang.Byte",new java.lang.Integer(BYTE));
            dict.put("java.lang.Short",new java.lang.Integer(SHORT));
            dict.put("java.lang.Integer",new java.lang.Integer(INTEGER));
            dict.put("java.lang.Long",new java.lang.Integer(LONG));

            dict.put("syntelos.xb.CF$Constants$Class",new java.lang.Integer(CONST_CLASS));
            dict.put("syntelos.xb.CF$Constants$FieldRef",new java.lang.Integer(CONST_FIELDREF));
            dict.put("syntelos.xb.CF$Constants$MethodRef",new java.lang.Integer(CONST_METHODREF));
            dict.put("syntelos.xb.CF$Constants$IMethodRef",new java.lang.Integer(CONST_IMETHODREF));
            dict.put("syntelos.xb.CF$Constants$String",new java.lang.Integer(CONST_STRING));
            dict.put("syntelos.xb.CF$Constants$Integer",new java.lang.Integer(CONST_INTEGER));
            dict.put("syntelos.xb.CF$Constants$Long",new java.lang.Integer(CONST_LONG));
            dict.put("syntelos.xb.CF$Constants$Float",new java.lang.Integer(CONST_FLOAT));
            dict.put("syntelos.xb.CF$Constants$Double",new java.lang.Integer(CONST_DOUBLE));
            dict.put("syntelos.xb.CF$Constants$NameAndType",new java.lang.Integer(CONST_NAME_AND_TYPE));
            dict.put("syntelos.xb.CF$Constants$Utf8",new java.lang.Integer(CONST_UTF8));
            dict.put("syntelos.xb.CF$Constants$Const$Nil",new java.lang.Integer(CONST));

            dict.put("op",new java.lang.Integer(OP));

            dict.put("syntelos.xb.at.Variable",new java.lang.Integer(VAR));
            dict.put("var",new java.lang.Integer(VAR));
        }
        public final static int DT4String(String type){
            java.lang.Integer re = (java.lang.Integer)dict.get(type);
            if (null != re)
                return re.intValue();
            else if (type.startsWith("syntelos.xb.op."))
                return OP;
            else
                throw new Error.Argument(type);
        }
        public final static char DT2Type(int type){
            switch (type){
            case BOOLEAN:
                return 'Z';
            case CHAR:
                return 'C';
            case FLOAT:
                return 'F';
            case DOUBLE:
                return 'D';
            case BYTE:
                return 'B';
            case SHORT:
                return 'S';
            case INTEGER:
                return 'I';
            case LONG:
                return 'J';
            default:
                return 'L';
            }
        }
        public final static String DT2String(int type){
            switch (type){
            case STRING:
            case CONST_STRING:
                return "string";
            case BOOLEAN:
                return "boolean";
            case CHAR:
                return "char";
            case FLOAT:
            case CONST_FLOAT:
                return "float";
            case DOUBLE:
            case CONST_DOUBLE:
                return "double";
            case BYTE:
                return "byte";
            case SHORT:
                return "short";
            case INTEGER:
            case CONST_INTEGER:
                return "int";
            case LONG:
            case CONST_LONG:
                return "long";
            case CONST_CLASS:
                return "class";
            case CONST_FIELDREF:
                return "field";
            case CONST_METHODREF:
                return "method";
            case CONST_IMETHODREF:
                return "interface-method";
            case CONST_NAME_AND_TYPE:
                return "name-and-type";
            case CONST_UTF8:
                return "utf8";
            case CONST:
                return "const";
            case OP:
                return "op";
            case VAR:
                return "var";
            default:
                throw new Error.Argument(java.lang.String.valueOf(type));
            }
        }
        public final static int DT4Object(java.lang.Object value){
            if (null == value)
                return STRING;
            else 
                return DT4String(value.getClass().getName());
        }
        public final static java.lang.Object DT2Object(IO base, int type, java.lang.Object value){
            if (null == value)
                return null;
            else {
                int value_type = DT4Object(value);
                if (type == value_type)
                    return value;
                else if (CONST <= value_type){
                    switch (value_type){
                    case OP:
                        switch (type){
                        case STRING:
                            return value.toString();
                        case OP:
                            return value;
                        case BOOLEAN:
                            return java.lang.Boolean.TRUE;
                        case INTEGER:
                            return new java.lang.Integer(((Op)value).getPC());
                        default:
                            throw new Error.Bug(base);
                        }
                    case VAR:
                        switch (type){
                        case STRING:
                            return value.toString();
                        case VAR:
                            return value;
                        case BOOLEAN:
                            return java.lang.Boolean.TRUE;
                        case INTEGER:
                            return new java.lang.Integer(((syntelos.xb.at.Variable)value).getSlotValue());
                        default:
                            throw new Error.Bug(base);
                        }
                    default:
                        CF.Constants.Const const_value = (CF.Constants.Const)value;
                        int const_tag = const_value.getTag();
                        switch (type){
                        case STRING:
                            /*
                             * Normal operand string value case 
                             */
                            return value.toString();
                        case BOOLEAN:
                            /*
                             * Convenience, "why not", case for value
                             */
                            switch (const_tag){
                            case CF.Constants.CLASS:
                            case CF.Constants.FIELDREF:
                            case CF.Constants.METHODREF:
                            case CF.Constants.IMETHODREF:
                            case CF.Constants.NAME_AND_TYPE:
                                return java.lang.Boolean.TRUE;
                            case CF.Constants.STRING:
                                java.lang.String string_string = ((CF.Constants.String)const_value).getString().getString();
                                if (null != string_string && 0 < string_string.length())
                                    return java.lang.Boolean.TRUE;
                                else
                                    return java.lang.Boolean.FALSE;
                            case CF.Constants.UTF8:
                                java.lang.String utf8_string = ((CF.Constants.Utf8)const_value).getString();
                                if (null != utf8_string && 0 < utf8_string.length())
                                    return java.lang.Boolean.TRUE;
                                else
                                    return java.lang.Boolean.FALSE;
                            case CF.Constants.INTEGER:
                            case CF.Constants.FLOAT:
                                java.lang.Number num32 = ((CF.Constants.Value1)const_value).getValue();
                                if (0 < num32.intValue())
                                    return java.lang.Boolean.TRUE;
                                else
                                    return java.lang.Boolean.FALSE;
                            case CF.Constants.LONG:
                            case CF.Constants.DOUBLE:
                                java.lang.Number num64 = ((CF.Constants.Value2)const_value).getValue();
                                if (0 < num64.intValue())
                                    return java.lang.Boolean.TRUE;
                                else
                                    return java.lang.Boolean.FALSE;
                            default:
                                throw new Error.Bug(base);
                            }
                        case CHAR:
                            /*
                             * Convenience, "why not", case for value
                             */
                            switch (const_tag){
                            case CF.Constants.INTEGER:
                            case CF.Constants.FLOAT:
                                java.lang.Number num32 = ((CF.Constants.Value1)const_value).getValue();
                                return new java.lang.Character((char)num32.intValue());
                            case CF.Constants.LONG:
                            case CF.Constants.DOUBLE:
                                java.lang.Number num64 = ((CF.Constants.Value2)const_value).getValue();
                                return new java.lang.Character((char)num64.intValue());
                            default:
                                throw new Error.Argument(base);
                            }
                        case FLOAT:
                            /*
                             * Convenience, "why not", case for value
                             */
                            switch (const_tag){
                            case CF.Constants.INTEGER:
                            case CF.Constants.FLOAT:
                                java.lang.Number num32 = ((CF.Constants.Value1)const_value).getValue();
                                return new java.lang.Float(num32.floatValue());
                            case CF.Constants.LONG:
                            case CF.Constants.DOUBLE:
                                java.lang.Number num64 = ((CF.Constants.Value2)const_value).getValue();
                                return new java.lang.Float(num64.floatValue());
                            default:
                                throw new Error.Argument(base);
                            }
                        case DOUBLE:
                            /*
                             * Convenience, "why not", case for value
                             */
                            switch (const_tag){
                            case CF.Constants.INTEGER:
                            case CF.Constants.FLOAT:
                                java.lang.Number num32 = ((CF.Constants.Value1)const_value).getValue();
                                return new java.lang.Double(num32.doubleValue());
                            case CF.Constants.LONG:
                            case CF.Constants.DOUBLE:
                                java.lang.Number num64 = ((CF.Constants.Value2)const_value).getValue();
                                return new java.lang.Double(num64.doubleValue());
                            default:
                                throw new Error.Argument(base);
                            }
                        case BYTE:
                            /*
                             * Convenience, "why not", case for value
                             */
                            switch (const_tag){
                            case CF.Constants.INTEGER:
                            case CF.Constants.FLOAT:
                                java.lang.Number num32 = ((CF.Constants.Value1)const_value).getValue();
                                return new java.lang.Byte(num32.byteValue());
                            case CF.Constants.LONG:
                            case CF.Constants.DOUBLE:
                                java.lang.Number num64 = ((CF.Constants.Value2)const_value).getValue();
                                return new java.lang.Byte(num64.byteValue());
                            default:
                                throw new Error.Argument(base);
                            }
                        case SHORT:
                            /*
                             * Convenience, "why not", case for value
                             */
                            switch (const_tag){
                            case CF.Constants.INTEGER:
                            case CF.Constants.FLOAT:
                                java.lang.Number num32 = ((CF.Constants.Value1)const_value).getValue();
                                return new java.lang.Short(num32.shortValue());
                            case CF.Constants.LONG:
                            case CF.Constants.DOUBLE:
                                java.lang.Number num64 = ((CF.Constants.Value2)const_value).getValue();
                                return new java.lang.Short(num64.shortValue());
                            default:
                                throw new Error.Argument(base);
                            }
                        case INTEGER:
                            {
                                /*
                                 * Normal operand value for index
                                 */
                                int idx = const_value.getIndex();
                                return new java.lang.Integer(idx);
                            }
                        case LONG:
                            /*
                             * Convenience, "why not", case for value
                             */
                            switch (const_tag){
                            case CF.Constants.INTEGER:
                            case CF.Constants.FLOAT:
                                java.lang.Number num32 = ((CF.Constants.Value1)const_value).getValue();
                                return new java.lang.Long(num32.longValue());
                            case CF.Constants.LONG:
                            case CF.Constants.DOUBLE:
                                java.lang.Number num64 = ((CF.Constants.Value2)const_value).getValue();
                                return new java.lang.Long(num64.longValue());
                            default:
                                throw new Error.Argument(base);
                            }
                        case CONST_CLASS:
                        case CONST_FIELDREF:
                        case CONST_METHODREF:
                        case CONST_IMETHODREF:
                        case CONST_STRING:
                        case CONST_INTEGER:
                        case CONST_FLOAT:
                        case CONST_LONG:
                        case CONST_DOUBLE:
                        case CONST_NAME_AND_TYPE:
                        case CONST_UTF8:
                        case CONST:

                            return value;

                        default:
                            throw new Error.Bug(base,java.lang.String.valueOf(type));
                        }
                    }
                }
                else {
                    switch (type){
                    case STRING:
                        return value.toString();
                    case BOOLEAN:
                        if (value instanceof java.lang.Number){
                            int int_value = ((java.lang.Number)value).intValue();
                            if (0 < int_value)
                                return java.lang.Boolean.TRUE;
                            else
                                return java.lang.Boolean.FALSE;
                        }
                        else {
                            java.lang.String string = value.toString();
                            if (null != string && 0 < string.length()){
                                IO.Uri uri = new IO.Uri(string);
                                if (uri.getPath().equalsIgnoreCase("true"))
                                    return java.lang.Boolean.TRUE;
                                else
                                    return java.lang.Boolean.FALSE;
                            }
                            else
                                return java.lang.Boolean.FALSE;
                        }
                    case CHAR:
                        if (value instanceof java.lang.Number){
                            int int_value = ((java.lang.Number)value).intValue();
                            if (0 < int_value)
                                return new java.lang.Character( (char)int_value);
                            else
                                throw new Error.Argument(base,"Invalid char value ("+int_value+").");
                        }
                        else {
                            java.lang.String string = value.toString();
                            if (null != string && 0 < string.length()){
                                IO.Uri uri = new IO.Uri(string);
                                return new java.lang.Character(uri.getPath().charAt(0));
                            }
                            else
                                throw new Error.Argument(base,"Empty string for character.");
                        }
                    case FLOAT:
                        if (value instanceof java.lang.Number){
                            float float_value = ((java.lang.Number)value).floatValue();
                            return new java.lang.Float( float_value);
                        }
                        else {
                            java.lang.String string = value.toString();
                            if (null != string && 0 < string.length())
                                try {
                                    IO.Uri uri = new IO.Uri(string);
                                    return new java.lang.Float(uri.getPath());
                                }
                                catch (java.lang.NumberFormatException nfx){
                                    Error err = new Error.State(base,string);
                                    err.initCause(nfx);
                                    throw err;
                                }
                            else
                                throw new Error.Argument(base,"Empty string for float.");
                        }
                    case DOUBLE:
                        if (value instanceof java.lang.Number){
                            double double_value = ((java.lang.Number)value).doubleValue();
                            return new java.lang.Double( double_value);
                        }
                        else {
                            java.lang.String string = value.toString();
                            if (null != string && 0 < string.length())
                                try {
                                    IO.Uri uri = new IO.Uri(string);
                                    return new java.lang.Double(uri.getPath());
                                }
                                catch (java.lang.NumberFormatException nfx){
                                    Error err = new Error.State(base,string);
                                    err.initCause(nfx);
                                    throw err;
                                }
                            else
                                throw new Error.Argument(base,"Empty string for double.");
                        }
                    case BYTE:
                        if (value instanceof java.lang.Number){
                            byte byte_value = ((java.lang.Number)value).byteValue();
                            return new java.lang.Byte( byte_value);
                        }
                        else {
                            java.lang.String string = value.toString();
                            if (null != string && 0 < string.length())
                                try {
                                    IO.Uri uri = new IO.Uri(string);
                                    return new java.lang.Byte(uri.getPath());
                                }
                                catch (java.lang.NumberFormatException nfx){
                                    Error err = new Error.State(base,string);
                                    err.initCause(nfx);
                                    throw err;
                                }
                            else
                                throw new Error.Argument(base,"Empty string for byte.");
                        }
                    case SHORT:
                        if (value instanceof java.lang.Number){
                            short short_value = ((java.lang.Number)value).shortValue();
                            return new java.lang.Short( short_value);
                        }
                        else {
                            java.lang.String string = value.toString();
                            if (null != string && 0 < string.length())
                                try {
                                    IO.Uri uri = new IO.Uri(string);
                                    return new java.lang.Short(uri.getPath());
                                }
                                catch (java.lang.NumberFormatException nfx){
                                    Error err = new Error.State(base,string);
                                    err.initCause(nfx);
                                    throw err;
                                }
                            else
                                throw new Error.Argument(base,"Empty string for short.");
                        }
                    case INTEGER:
                        if (value instanceof java.lang.Number){
                            int int_value = ((java.lang.Number)value).intValue();
                            return new java.lang.Integer( int_value);
                        }
                        else {
                            java.lang.String string = value.toString();
                            if (null != string && 0 < string.length()){
                                IO.Uri uri = new IO.Uri(string);
                                switch (CF.Constants.Scheme(uri)){
                                case CF.Constants.NIL:
                                case CF.Constants.INTEGER:
                                    try {
                                        return java.lang.Integer.decode(uri.getPath());
                                    }
                                    catch (java.lang.NumberFormatException nfx){
                                        Error number_err = new Error.State(base,string);
                                        number_err.initCause(nfx);
                                        throw number_err;
                                    }
                                    //break//(unreachable)
                                default:
                                    CF.Constants constants = base.getConstants();
                                    try {
                                        CF.Constants.Const constant = constants.getConst(uri);
                                        int constant_index = constant.getIndex();
                                        return new java.lang.Integer(constant_index);
                                    }
                                    catch (Error.Argument const_err){
                                        /*
                                         * Extra handling to benefit
                                         * XA implementation of
                                         * (B/S/IPUSH) from XA:LOAD
                                         */
                                        java.lang.String scheme = uri.getSchemeHead();
                                        if ("byte".equals(scheme)||
                                            "short".equals(scheme))
                                            {
                                                try {
                                                    return java.lang.Integer.decode(uri.getPath());
                                                }
                                                catch (java.lang.NumberFormatException nfx){
                                                    Error number_err = new Error.State(base,string);
                                                    number_err.initCause(nfx);
                                                    throw number_err;
                                                }
                                            }
                                        throw const_err;
                                    }
                                }
                            }
                            else
                                throw new Error.Argument(base,"Empty string for integer.");
                        }
                    case LONG:
                        if (value instanceof java.lang.Number){
                            long long_value = ((java.lang.Number)value).longValue();
                            return new java.lang.Long( long_value);
                        }
                        else {
                            java.lang.String string = value.toString();
                            if (null != string && 0 < string.length())
                                try {
                                    IO.Uri uri = new IO.Uri(string);
                                    return java.lang.Long.decode(uri.getPath());
                                }
                                catch (java.lang.NumberFormatException nfx){
                                    Error err = new Error.State(base,string);
                                    err.initCause(nfx);
                                    throw err;
                                }
                            else
                                throw new Error.Argument(base,"Empty string for long.");
                        }
                    case CONST_CLASS:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constClass(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_FIELDREF:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constFieldRef(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_METHODREF:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constMethodRef(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_IMETHODREF:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constIMethodRef(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_STRING:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constString(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_INTEGER:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constInteger(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_FLOAT:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constFloat(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_LONG:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constLong(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_DOUBLE:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constDouble(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_NAME_AND_TYPE:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constNameAndType(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case CONST_UTF8:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.constUtf8(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    case VAR:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            syntelos.xb.at.LocalVariableTable locals = base.getAttributeLocalVariableTable();
                            return locals.getVar(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            syntelos.xb.at.LocalVariableTable locals = base.getAttributeLocalVariableTable();
                            return locals.getVar(idx);
                        }
                        else
                            return null;//(not found)
                    case OP:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            syntelos.xb.at.Code code = base.getAttributeCode();
                            return code.getOp(uri);
                        }
                        else if (INTEGER == value_type){
                            int pc = ((java.lang.Integer)value).intValue();
                            syntelos.xb.at.Code code = base.getAttributeCode();
                            return code.getOpByPC(pc);
                        }
                        else
                            return null;//(not found)
                    case CONST:
                        if (STRING == value_type){
                            String string = (String)value;
                            IO.Uri uri = new IO.Uri(string);
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(uri);
                        }
                        else if (INTEGER == value_type){
                            int idx = ((java.lang.Integer)value).intValue();
                            CF.Constants constants = base.getConstants();
                            return constants.getConst(idx);
                        }
                        else
                            return null;//(not found)
                    default:
                        throw new Error.Bug(base,java.lang.String.valueOf(type));
                    }
                }
            }
        }
    }


    /**
     * <p> An absolute URI has a scheme and path.  </p>
     */
    public static class Uri 
        extends syntelos.iou.uri
    {
        /**
         * @param string An integer string for Integer decode
         * @return An integer decoded from the string value operand
         * @exception syntelos.xb.Error$Argument Caused by number
         * format exception
         */
        public final static int Integer(java.lang.String string)
            throws syntelos.xb.Error.Argument
        {
            if (null == string)
                throw new Error.Argument("Null argument");
            else 
                try {
                    return java.lang.Integer.decode(string).intValue();
                }
                catch (java.lang.NumberFormatException nfx){
                    Error.Argument err = new Error.Argument(string);
                    err.initCause(nfx);
                    throw err;
                }
        }
        /**
         * @param string An integer string for Integer decode
         * @param default_value Returned for a null, empty or
         * otherwise unparseable string
         * @return An integer decoded from the string value operand, or the default value
         */
        public final static int Integer(java.lang.String string, int default_value)
            throws syntelos.xb.Error.Argument
        {
            if (null == string)
                return default_value;
            else 
                try {
                    return java.lang.Integer.decode(string).intValue();
                }
                catch (java.lang.NumberFormatException nfx){

                    return default_value;
                }
        }
        /** 
         * @param uri URI string
         */
        public Uri(String uri){
            super(uri);
        }
        /** 
         * <p> Edit ctor. </p>
         * 
         * @param uri URI String
         * @param int Truncate type from product: see {@link
         * syntelos.iou.uri} for info on type values
         */
        public Uri(Uri uri, int truncate){
            super(uri,truncate);
        }
    }

    public syntelos.xb.CF.Constants getConstants();

    public syntelos.xb.Class getDeclaringClass();

    public syntelos.xb.at.LocalVariableTable getAttributeLocalVariableTable();

    public syntelos.xb.at.Code getAttributeCode();

}
